import * as mysql2 from "mysql2/promise";

import { isDevelopment, logger } from ".";
import * as process from "node:process";

export function createMysql() {
  logger("Creating database...");
  const pool = (mysql2 as any).createPool({
    host: process.env.DB_HOST,
    user: process.env.DB_USER,
    password: process.env.DB_PASSWORD,
    database: process.env.DB_NAME,
    port: process.env.DB_PORT,
  });
  pool
    .getConnection()
    .then((connection: any) => {
      if (connection) {
        logger("✅ Connection established successfully.");
        createDao(connection);
      }
    })
    .catch((err: any) => {
      logger("❌ Error connecting to database:" + err);
    });
}

let db: { query: (arg0: string, arg1?: any[]) => PromiseLike<[any]> | [any] };
function createDao(c) {
  db = c;
  if (!isDevelopment() && process.env.DB_HEARTBEAT === "true") {
    heartbeat();
  }
}

// 定期发送心跳查询
function heartbeat() {
  let cnt = 0;
  setInterval(async () => {
    try {
      await db.query("SELECT 1");
      cnt++;
      if (process.env.DB_HEARTBEATLOG === "true") {
        logger("✅ Heartbeat sent to keep the connection alive." + cnt);
      }
    } catch (err) {
      logger("❌ Heartbeat query failed:" + err);
    }
  }, process.env.DB_HEARTBEATTIME as any);
}

/**
 *
 * @param strings
 * @param values
 * @returns
 */
export async function sql<T = any>(strings, ...values): Promise<T[]> {
  const params = [];
  const query = strings.reduce((acc, str, i) => {
    acc += str + (i < values.length ? "?" : "");
    if (i < values.length) params.push(values[i]);
    return acc;
  }, "");
  return createSql(query, params);
}

/**
 *
 * @param strings
 * @param values
 * @returns
 */
export async function createSql<T = any>(query, params?): Promise<T[]> {
  const [rows] = await db.query(query, params);
  return rows;
}
